package my.app;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;

import my.app.company.Company;
import my.app.taxi.Taxi;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.AndroidHttpTransport;
import org.xmlpull.v1.XmlPullParserException;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;

public class ServiceClient {
	
	private static String host = Settings.getInstance().getHost();
	
	private static ServiceClient instance = null;
	ArrayList<Taxi> availableTaxi = new ArrayList<Taxi>();
	ArrayList<Company> availableCompanies = new ArrayList<Company>();
	private ArrayList<Company> favorites = new ArrayList<Company>();
	Context context;
	private int FlagFavorites = 1;
	
	private Location myLocation;
	
	private ServiceClient(final Context context) {
		this.context = context;
		Location l = new Location("my");
		l.setLatitude(Settings.getInstance().getLat());
		l.setLongitude(Settings.getInstance().getLon());
		this.setMyLocation(l);
		
		
		this.availableTaxi = getAllAvailableTaxi();
		this.availableCompanies = getAllAvailableCompanies();
		
		
		//Get My Location...
		LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
		
		
		
		
	}
	public double CalculationByDistance(GeoPoint StartP, GeoPoint EndP) {
        double lat1 = StartP.getLatitudeE6()/1E6;
        double lat2 = EndP.getLatitudeE6()/1E6;
        double lon1 = StartP.getLongitudeE6()/1E6;
        double lon2 = EndP.getLongitudeE6()/1E6;
        double dLat = Math.toRadians(lat2-lat1);
        double dLon = Math.toRadians(lon2-lon1);
        double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
        Math.sin(dLon/2) * Math.sin(dLon/2);
        double c = 2 * Math.asin(Math.sqrt(a));
        return 6371 * c;
	}
	
	
	public static ServiceClient getInstance(Context context) {
		if(instance == null) {
	         instance = new ServiceClient(context);
	    }
	      
		return instance;

		
	}
	
	
	
	public ArrayList<Taxi> getAvailableTaxi() {
		return availableTaxi;
	}

	public ArrayList<Company> getAvailableCompanies() {
		return availableCompanies;
	}

	public ArrayList<Company> getFavorites() {
		// TODO Auto-generated method stub
		if (FlagFavorites == 1) {
			ArrayList<Company> a = new ArrayList<Company>();
			ArrayList<Integer> ids = new ArrayList<Integer>();
			
			
			try {
				SoapObject request = new SoapObject("service4Cab", "getFavorites");
				request.addProperty("username", Settings.getInstance().getUsername());
				SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
				envelope.setOutputSoapObject(request);
				AndroidHttpTransport aht = new AndroidHttpTransport(host);
				aht.call("service4Cab", envelope);
				
				SoapObject result = (SoapObject) envelope.bodyIn;
				String s = result.getProperty("return").toString();
				String ss[] = s.split("-");
				for (String sss : ss) {
					ids.add(Integer.parseInt(sss));
				}
				
				 
				
			} catch (Exception e) {
			}
			
			
			for (int i : ids) {
			
				Company c = getCompany(i);
				if (c!=null) {
					a.add(c);
				}
				
			}
			favorites = a;
			FlagFavorites = 0;
			return a;
		}
		else {
			FlagFavorites = 0;
			return favorites;
			
		}
		
	}
	
	
	private ArrayList<Taxi> getAllAvailableTaxi() {
		ArrayList<Taxi> listTaxi = new ArrayList<Taxi>();
		ArrayList<Integer> ids = new ArrayList<Integer>();
		
		try {
			SoapObject request = new SoapObject("service4Cab", "getAvailableTaxi");
			SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
			envelope.setOutputSoapObject(request);
			AndroidHttpTransport aht = new AndroidHttpTransport(host);
			aht.call("service4Cab", envelope);
			
			SoapObject result = (SoapObject) envelope.bodyIn;
			String s = result.getProperty("return").toString();
			String ss[] = s.split("-");
			for (String sss : ss) {
				ids.add(Integer.parseInt(sss));
			}
			
			 
			
		} catch (Exception e) {
		}
		
		
		
		
		
		
		for (int i : ids) {
			
			Taxi t = getTaxi(i);
			if (t!=null) {
				listTaxi.add(t);
			}
			
		}
		
		return listTaxi;
	}
	
	private ArrayList<Company> getAllAvailableCompanies() {
		ArrayList<Company> listCompanies = new ArrayList<Company>();
		ArrayList<Integer> ids = new ArrayList<Integer>();

		try {
			SoapObject request = new SoapObject("service4Cab", "getAvailableCompanies");
			SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
			envelope.setOutputSoapObject(request);
			AndroidHttpTransport aht = new AndroidHttpTransport(host);
			aht.call("service4Cab", envelope);
			
			SoapObject result = (SoapObject) envelope.bodyIn;
			String s = result.getProperty("return").toString();
			String ss[] = s.split("-");
			for (String sss : ss) {
				ids.add(Integer.parseInt(sss));
			}
			
			 
			
		} catch (Exception e) {
		}
		
		
		for (int i : ids) {
			
			Company c = getCompany(i);
			if (c!=null) {
				listCompanies.add(c);
			}
			
		}
		
		return listCompanies;
	}
	
	
	
	private Taxi getTaxi(int id) {
		//Creating Taxi class and Set attrs...
		Taxi t = null;
		try {
			SoapObject request = new SoapObject("service4Cab", "getTaxi");
			request.addProperty("id", id);
			SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
			envelope.setOutputSoapObject(request);
			AndroidHttpTransport aht = new AndroidHttpTransport(host);
			aht.call("service4Cab", envelope);
			
			SoapObject result = (SoapObject) envelope.bodyIn;
			SoapObject results = (SoapObject) result.getProperty(0);
			
			t = new Taxi();
			
			//Set Car Model..
			t.setCarModel(results.getProperty("car_model").toString());
			
			//Set GeoPoint...
			double lat = Double.parseDouble(results.getProperty("lat").toString());
			double lon = Double.parseDouble(results.getProperty("lon").toString());
			int lt = (int) (lat*1E6);
			int ln = (int) (lon*1E6);
			GeoPoint geoPoint = new GeoPoint(lt, ln);
			t.setGeoPoint(geoPoint);
			
			//Set icon...
			t.setIcon(results.getProperty("icon").toString());
			
			//set CompIcon..
			String ci = results.getProperty("icon").toString();
			ci = ci.replace("t", "c");
			t.setCompIcon(ci);
			
			//Set Taxi id..
			t.setId(id);
			
			//Set Information...
			t.setInformation(results.getProperty("comment").toString());
			
			//Set Licance Plate...
			t.setLicenceTag(results.getProperty("plate").toString());
			
			//Set Ratings...
			t.setRating(Double.parseDouble(results.getProperty("rating").toString()));
			
			//Set Ratings Count...
			t.setRatingCount(Integer.parseInt(results.getProperty("rating_count").toString()));
			
			//Set Services..
			ArrayList<String> s = new ArrayList<String>();
			String ss = results.getProperty("services").toString();
			String[] sss = ss.split(";");
			for (String x : sss) {
				s.add(x);
			}
			t.setServices(s);
			
			//Set Phone...
			t.setTel(results.getProperty("phone").toString());
			
			
			// Set Adress..
			t.setAddress("dsadsadsadasdsa");
			
			
			//TODO Set Distance
			Location l = new Location("a");
			l.setLatitude(lt);
			l.setLongitude(ln);
			double ddd = l.distanceTo(myLocation);
			ddd = ddd/1000000;
			t.setDistance(ddd);
			
			//set comp id..
			t.setComp_id((Integer)results.getProperty("comp_id"));
			
			//set comp name..
			t.setComp_name(results.getProperty("comp_name").toString());
			
		} catch (Exception e) {
		}
		if (t==null) t=getTaxi(id);
		
		
		return t;
	}
		
	public Company getCompany(int id) {
		Company c = null;
		try {
			SoapObject request = new SoapObject("service4Cab", "getCompany");
			request.addProperty("id", id);
			SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
			envelope.setOutputSoapObject(request);
			AndroidHttpTransport aht = new AndroidHttpTransport(host);
			aht.call("service4Cab", envelope);
			
			SoapObject result = (SoapObject) envelope.bodyIn;
			SoapObject results = (SoapObject) result.getProperty(0);
			
			c = new Company();
			
			
			
			//Set GeoPoint...
			double lat = Double.parseDouble(results.getProperty("lat").toString());
			double lon = Double.parseDouble(results.getProperty("lon").toString());
			int lt = (int) (lat*1E6);
			int ln = (int) (lon*1E6);
			GeoPoint geoPoint = new GeoPoint(lt, ln);
			c.setGeoPoint(geoPoint);
			
			//Set icon...
			c.setIcon(results.getProperty("icon").toString());
			
			//Set Company id..
			c.setId(id);
			
			//Set Company Name..
			c.setName(results.getProperty("name").toString());
			
			//Set Information...
			c.setInformation(results.getProperty("comment").toString());
			
			
			//Set Ratings...
			c.setRating(Double.parseDouble(results.getProperty("rating").toString()));
			
			//Set Ratings Count...
			c.setRatingCount(Integer.parseInt(results.getProperty("rating_count").toString()));
			
			//Set Services..
			ArrayList<String> s = new ArrayList<String>();
			String ss = results.getProperty("services").toString();
			String[] sss = ss.split(";");
			for (String x : sss) {
				s.add(x);
			}
			c.setServices(s);
			
			//Set Phone...
			c.setTel(results.getProperty("phone").toString());
			
			//Set Adress..
			c.setAddress(results.getProperty("address").toString());
			
			
			//TODO Set Distance
			Location l = new Location("a");
			l.setLatitude(lt);
			l.setLongitude(ln);
			double ddd = l.distanceTo(myLocation);
			ddd = ddd/1000000;
			c.setDistance(ddd);
			
			//Set Email..
			c.setEmail(results.getProperty("email").toString());
			
			//Set Web URL...
			c.setWeb(results.getProperty("web").toString());
			
		} catch (Exception e) {
		}
		if (c==null) c=getCompany(id);
		
		
		return c;
	}
	
	
	
	public static int getDrawableId(String icon) {
    	int id = R.drawable.t1;
    	
    	if (icon.equals("t1")) id = R.drawable.t1;
    	if (icon.equals("t2")) id = R.drawable.t2;
    	if (icon.equals("t3")) id = R.drawable.t3;
    	if (icon.equals("t4")) id = R.drawable.t4;
    	if (icon.equals("t5")) id = R.drawable.t5;
    	if (icon.equals("t6")) id = R.drawable.t6;
    	if (icon.equals("t7")) id = R.drawable.t7;
    	if (icon.equals("t8")) id = R.drawable.t8;
    	if (icon.equals("c1")) id = R.drawable.c1;
    	if (icon.equals("c2")) id = R.drawable.c2;
    	if (icon.equals("c3")) id = R.drawable.c3;
    	if (icon.equals("c4")) id = R.drawable.c4;
    	if (icon.equals("c5")) id = R.drawable.c5;
    	if (icon.equals("c6")) id = R.drawable.c6;
    	if (icon.equals("c7")) id = R.drawable.c7;
    	if (icon.equals("c8")) id = R.drawable.c8;
    	if (icon.equals("1.0")) id = R.drawable.s1;
    	if (icon.equals("2.0")) id = R.drawable.s2;
    	if (icon.equals("3.0")) id = R.drawable.s3;
    	if (icon.equals("4.0")) id = R.drawable.s4;
    	if (icon.equals("5.0")) id = R.drawable.s5;
    	if (icon.equals("1.5")) id = R.drawable.s15;
    	if (icon.equals("2.5")) id = R.drawable.s25;
    	if (icon.equals("3.5")) id = R.drawable.s35;
    	if (icon.equals("4.5")) id = R.drawable.s45;

    	
    	return id;
    }
	
	public static int getStarID(String icon) {
		int id = R.drawable.bs25;
		if (icon.equals("1.0")) id = R.drawable.bs1;
    	if (icon.equals("2.0")) id = R.drawable.bs2;
    	if (icon.equals("3.0")) id = R.drawable.bs3;
    	if (icon.equals("4.0")) id = R.drawable.bs4;
    	if (icon.equals("5.0")) id = R.drawable.bs5;
    	if (icon.equals("1.5")) id = R.drawable.bs15;
    	if (icon.equals("2.5")) id = R.drawable.bs25;
    	if (icon.equals("3.5")) id = R.drawable.bs35;
    	if (icon.equals("4.5")) id = R.drawable.bs45;
    	return id;
	}

	
	

	public void rateCompany(String username, int rate) {
		try {
			SoapObject request = new SoapObject("service4Cab", "rateCompany");
			request.addProperty("username", username);
			request.addProperty("rate", rate);
			SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
			envelope.setOutputSoapObject(request);
			AndroidHttpTransport aht = new AndroidHttpTransport(host);
			
			aht.call("service4Cab", envelope);
			
			SoapObject result = (SoapObject) envelope.bodyIn;
			
			
			 
			
		} catch (Exception e) {
		}
	}
	
	public void rateTaxi(String username, int rate) {
		try {
			SoapObject request = new SoapObject("service4Cab", "rateTaxi");
			request.addProperty("username", username);
			request.addProperty("rate", rate);
			SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
			envelope.setOutputSoapObject(request);
			AndroidHttpTransport aht = new AndroidHttpTransport(host);
			
			aht.call("service4Cab", envelope);
			
			SoapObject result = (SoapObject) envelope.bodyIn;
			
			
			 
			
		} catch (Exception e) {
		}
	}
	
	public void addFavorite(String username, int cid) {
		try {
			SoapObject request = new SoapObject("service4Cab", "addFavorite");
			request.addProperty("username", username);
			request.addProperty("cid", cid);
			SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
			envelope.setOutputSoapObject(request);
			AndroidHttpTransport aht = new AndroidHttpTransport(host);
			
			aht.call("service4Cab", envelope);
			
			SoapObject result = (SoapObject) envelope.bodyIn;
			
			
			 
			
		} catch (Exception e) {
		}
	}
	
	public void removeFavorite(String username, int cid) {
		try {
			SoapObject request = new SoapObject("service4Cab", "removeFavorite");
			request.addProperty("username", username);
			request.addProperty("cid", cid);
			SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
			envelope.setOutputSoapObject(request);
			AndroidHttpTransport aht = new AndroidHttpTransport(host);
			
			aht.call("service4Cab", envelope);
			
			SoapObject result = (SoapObject) envelope.bodyIn;
			
			
			 
			
		} catch (Exception e) {
		}
	}
	
	
	
	public void setFavorites(ArrayList<Company> favorites) {
		this.favorites = favorites;
	}
	
	public void setFlagFavorites(int flagFavorites) {
		FlagFavorites = flagFavorites;
	}

	public int getFlagFavorites() {
		return FlagFavorites;
	}

	public void setMyLocation(Location myLocation) {
		this.myLocation = myLocation;
	}

	public Location getMyLocation() {
		return myLocation;
	}

	
	
	
	
	
	
}
